/*
 * Copyright 2018 Zhongan.com All right reserved. This software is the
 * confidential and proprietary information of Zhongan.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Zhongan.com.
 */

package com.zhongan.cloud.gateway.filter.previous;

import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;

import java.net.URI;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

/**
 * 集成原有网关
 *
 * @author tongyufu
 */
@Component
public class PreviousIntranetFilterFactory extends AbstractGatewayFilterFactory<PreviousIntranetFilterFactory.Config> {

    @Autowired
    private PreviousService previousService;

    public PreviousIntranetFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest req = exchange.getRequest();
            addOriginalRequestUrl(exchange, req.getURI());
            String newPath = req.getURI().getRawPath();
            URI uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8080" + newPath).build().toUri();
            //URI uri = previousService.fetchTargetUri(req);
            ServerHttpRequest request = req.mutate().uri(uri).build();
            //直接修改request的uri无效，参见 https://my.oschina.net/tongyufu/blog/1836589
            Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
            Route newRoute = Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters())
                    .id(route.getId()).order(route.getOrder()).uri(uri).build();
            exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, newRoute);
            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    public static class Config {
    }
}
